package main

import (
	"context"
	"log"
	"time"
)

type otherContext struct {
	context.Context
}
   
func main() {
	ctxa, cancel := context.WithCancel(context.Background())

	go work(ctxa, "work1")

	tm := time.Now().Add(3 * time.Second)
	ctxb, cancel := context.WithDeadline(ctxa, tm)

	go work(ctxb, "work2")

	oc := otherContext{ctxb}
	ctxc := context.WithValue(oc, "key", "测试存储key-bal")

	go workWithVal(ctxc, "work3")

	time.Sleep(10 * time.Second)

	// 调用取消方法退出                                                                   
	cancel()
	time.Sleep(5* time.Second)
	log.Println("main stop")
}

func work(ctx context.Context, name string) {
	for {
		select {
		case <-ctx.Done():
			log.Println("收到取消命令,name:=", name)
			return
		default:
			log.Println("运行中,name:=", name)
			time.Sleep(1 * time.Second)
		}
	}
}

func workWithVal(ctx context.Context, name string) {
	for {
		select {
		case <-ctx.Done():
			log.Println("收到取消命令,name:=", name)
			return
		default:
			val := ctx.Value("key").(string)
			log.Printf("运行中,name:=%s value:=%s\n", name, val)
			time.Sleep(1 * time.Second)
		}
	}
}
